#ifndef FILEOP_H
#define FILEOP_H

#include <list>
#include <iostream>
#include <filesystem>
#include <fstream>


namespace fs = std::filesystem;

static void clearFolderContents(const fs::path& folderPath)
{
    try
    {
        for (const auto& entry : fs::directory_iterator(folderPath))
        {
            if (fs::is_directory(entry))
            {
                // 如果是子目录，递归删除其内容
                clearFolderContents(entry);
                // 删除空的子目录
                fs::remove(entry);
            }
            else
            {
                // 如果是文件，直接删除
                fs::remove(entry);
            }
        }
    }
    catch (const fs::filesystem_error& e)
    {
        std::cerr << "Error: " << e.what() << std::endl;
    }
}

static std::string GetCurrentDir(bool parent = false)
{
    // 获取当前工作目录
    fs::path currentDir = fs::current_path();
    std::string ret;
    ret = currentDir.string();

    if(parent){
        ret =  currentDir.parent_path().string();
    }

    // 输出当前工作目录
    std::cout << "当前工作目录: " << ret  << std::endl;
    return ret;
}

static void copyDirectoryRecursively(const fs::path& sourceDir, const fs::path& destDir) {
    try {
        // 检查源目录是否存在并且是一个目录
        if (!fs::exists(sourceDir) || !fs::is_directory(sourceDir)) {
            throw std::runtime_error("源目录不存在或不是一个有效的目录: " + sourceDir.string());
        }

        // 确保目标目录存在，如果不存在则创建它
        if (!fs::exists(destDir)) {
            fs::create_directories(destDir);
        }

        // 使用 recursive_directory_iterator 遍历源目录及其子目录
        for (const auto& entry : fs::recursive_directory_iterator(sourceDir)) {
            // 获取相对路径
            fs::path relativePath = fs::relative(entry.path(), sourceDir);

            // 构造目标路径
            fs::path targetPath = destDir / relativePath;

            if (entry.is_regular_file()) {
                // 如果是文件，则确保目标路径的父目录存在
                if (!fs::exists(targetPath.parent_path())) {
                    fs::create_directories(targetPath.parent_path());
                }

                // 检查目标文件是否已经存在
                if (fs::exists(targetPath)) {
                    std::cout << "文件已存在，跳过: " << targetPath << '\n';
                    continue;
                }

                // 复制文件
                fs::copy_file(entry.path(), targetPath, fs::copy_options::update_existing);
                std::cout << "复制文件: " << entry.path() << " 到 " << targetPath << '\n';
            } else if (entry.is_directory()) {
                // 如果是目录，则确保目标目录存在
                if (!fs::exists(targetPath)) {
                    fs::create_directory(targetPath);
                    std::cout << "创建目录: " << targetPath << '\n';
                }
            } else {
                std::cout << "跳过非文件/目录条目: " << entry.path() << '\n';
            }
        }
    } catch (const fs::filesystem_error& e) {
        std::cerr << "文件系统错误: " << e.what() << '\n';
    } catch (const std::exception& e) {
        std::cerr << "错误: " << e.what() << '\n';
    }
}


// 定义删除文件的函数
static void deleteFile(const std::string& filePath) {
    try {
        // 将字符串转换为路径对象
        fs::path path(filePath);

        // 检查文件是否存在
        if (fs::exists(path)) {
            // 检查是否是常规文件（而不是目录）
            if (fs::is_regular_file(path)) {
                // 删除文件
                bool result = fs::remove(path);
                if (result) {
                    std::cout << "成功删除文件: " << filePath << '\n';
                } else {
                    std::cerr << "无法删除文件: " << filePath << '\n';
                }
            } else {
                // std::cout << "路径不是文件: " << filePath << '\n';
            }
        } else {
            std::cerr << "文件不存在: " << filePath << '\n';
        }
    } catch (const fs::filesystem_error& e) {
        // 捕获并处理文件系统相关的异常
        std::cerr << "文件系统错误: " << e.what() << '\n';
    } catch (const std::exception& e) {
        // 捕获其他可能的异常
        std::cerr << "发生错误: " << e.what() << '\n';
    }
}

// 定义递归创建多级目录的函数
static void createDirectories(const std::string& dirPath) {
    try {
        // 将字符串转换为路径对象
        fs::path path(dirPath);

        // 递归创建目录
        bool created = fs::create_directories(path);
        if (created) {
            std::cout << "成功创建多级目录: " << dirPath << '\n';
        } else {
            // std::cout << "目录已存在或部分目录已存在: " << dirPath << '\n';
        }
    } catch (const fs::filesystem_error& e) {
        // 捕获并处理文件系统相关的异常
        std::cerr << "文件系统错误: " << e.what() << '\n';
    } catch (const std::exception& e) {
        // 捕获其他可能的异常
        std::cerr << "发生错误: " << e.what() << '\n';
    }
}

// 定义获取目录下所有文件夹列表的函数
static std::list<std::string> getSubdirectories(const std::string& dirPath) {
    std::list<std::string> subdirs;

    try {
        // 将字符串转换为路径对象
        fs::path path(dirPath);

        // 检查目录是否存在并且是目录
        if (!fs::exists(path) || !fs::is_directory(path)) {
            throw std::runtime_error("指定路径不存在或不是一个有效的目录: " + dirPath);
        }

        // 遍历目录中的所有条目
        for (const auto& entry : fs::directory_iterator(path)) {
            // 检查是否是子目录
            if (fs::is_directory(entry.status())) {
                // 将子目录路径添加到列表中（可以使用相对路径）
                // subdirs.push_back(entry.path().filename().string()); // 仅获取文件夹名称
                // 或者使用绝对路径：
                subdirs.push_back(entry.path().string());
            }
        }
    } catch (const fs::filesystem_error& e) {
        // 捕获并处理文件系统相关的异常
        std::cerr << "文件系统错误: " << e.what() << '\n';
        throw; // 重新抛出异常给调用者
    } catch (const std::exception& e) {
        // 捕获其他可能的异常
        std::cerr << "发生错误: " << e.what() << '\n';
        throw; // 重新抛出异常给调用者
    }

    return subdirs;
}

// 定义获取目录下所有文件夹列表的函数
static std::list<fs::path > getSubdirectoriesPath(const std::string& dirPath) {
    std::list<fs::path > subdirs;

    try {
        // 将字符串转换为路径对象
        fs::path path(dirPath);

        // 检查目录是否存在并且是目录
        if (!fs::exists(path) || !fs::is_directory(path)) {
            throw std::runtime_error("指定路径不存在或不是一个有效的目录: " + dirPath);
        }

        // 遍历目录中的所有条目
        for (const auto& entry : fs::directory_iterator(path)) {
            // 检查是否是子目录
            if (fs::is_directory(entry.status())) {
                // 将子目录路径添加到列表中（可以使用相对路径）
                // subdirs.push_back(entry.path().filename().string()); // 仅获取文件夹名称
                // 或者使用绝对路径：
                subdirs.push_back(entry.path());
            }
        }
    } catch (const fs::filesystem_error& e) {
        // 捕获并处理文件系统相关的异常
        std::cerr << "文件系统错误: " << e.what() << '\n';
        throw; // 重新抛出异常给调用者
    } catch (const std::exception& e) {
        // 捕获其他可能的异常
        std::cerr << "发生错误: " << e.what() << '\n';
        throw; // 重新抛出异常给调用者
    }

    return subdirs;
}


static void WriteStr2File(std::string filePath,std::string str)
{
    std::ofstream file(filePath);

    if (!file.is_open()) {
        throw std::runtime_error("无法打开文件: " + filePath);
    }
    file<<str;
    file.close();
}

#endif // FILEOP_H
